#include "CAnimationManager.h"
#include "Wrappers\tinyxml.h"
#include "Wrappers\CSGD_TextureManager.h"
#include "Wrappers\CSGD_Direct3D.h"

CAnimationManager::CAnimationManager(void)
{
	nextAvailableIndex = -1;
}

CAnimationManager::~CAnimationManager(void)
{
	for(unsigned int i = 0; i < m_vAnimations.size(); ++i)
		delete m_vAnimations[i];
}

CAnimationManager* CAnimationManager::GetInstance()
{
	static CAnimationManager instance;
	return &instance;
}

// Returns an ID for the animation to be used with the Play function
int CAnimationManager::Load(string filename, DWORD dwColor)
{
	// Create a new animation to be loaded
	CAnimation* anim = new CAnimation();

	// Open the doc and set up the root
	TiXmlDocument doc;
	doc.LoadFile(filename.c_str());
	TiXmlElement *rootEl = doc.RootElement();
	TiXmlNode* root = rootEl->FirstChild();

	// Read in all of the data
	//////////////////////////
	
	// Image Filename
	string fileName = root->FirstChildElement("FileName")->FirstChild()->Value();
	string path = "Resource\\Graphics\\";
	path.append(fileName.c_str());
	anim->SetImageID(CSGD_TextureManager::GetInstance()->LoadTexture(path.c_str(),dwColor));//D3DCOLOR_XRGB(34,190,34)));
	// Looping
	anim->SetIsLooping(strcmp(root->FirstChildElement("IsLooping")->FirstChild()->Value(), "true") == 0);
	
	// Read in all of the Frames
	TiXmlElement* frame = root->FirstChildElement("Frame");
	if(!frame)
		return -1;
	
	while(frame)
	{
		CFrame* temp = new CFrame();
		// Frame Duration
		temp->SetFrameDuration((float)atof(frame->FirstChildElement("FrameDuration")->FirstChild()->Value()));
		
		// Render Rect
		RECT rect;
		rect.left = atoi(frame->FirstChildElement("RenderRectX")->FirstChild()->Value());
		rect.right = atoi(frame->FirstChildElement("RenderRectX1")->FirstChild()->Value());
		rect.top = atoi(frame->FirstChildElement("RenderRectY")->FirstChild()->Value());
		rect.bottom = atoi(frame->FirstChildElement("RenderRectY1")->FirstChild()->Value());
		temp->SetRenderRect(rect);

		// Anchor Point
		temp->SetAnchorX(atoi(frame->FirstChildElement("AnchorPointX")->FirstChild()->Value()));
		temp->SetAnchorY(atoi(frame->FirstChildElement("AnchorPointY")->FirstChild()->Value()));

		anim->PushFrame(temp);
		frame = frame->NextSiblingElement("Frame");
	}

	m_vAnimations.push_back(anim);
	++nextAvailableIndex;
	return nextAvailableIndex;
}

void CAnimationManager::Play(int nPosX, int nPosY, float scaleX, float scaleY, int nIndex)
{
	if(nIndex < 0 || nIndex > (int)m_vAnimations.size() - 1)
		return;

	CAnimation* anim = m_vAnimations[nIndex];

	CSGD_TextureManager::GetInstance()->Draw(anim->GetImageID(), nPosX, nPosY, scaleX, scaleY, 
		&anim->GetFrames()->operator[](anim->GetCurrentFrame())->GetRenderRect());
}

// Only directly call this function for testing (use UpdateAllAnimations)
void CAnimationManager::UpdateAnimation(float elapsedTime, int nIndex)
{
	CAnimation* anim = m_vAnimations[nIndex];
	anim->SetFrameTime(anim->GetFrameTime() + elapsedTime);

	if(anim->GetAnimationSpeed() * anim->GetFrames()->operator[](anim->GetCurrentFrame())->GetFrameDuration() * 0.001 < anim->GetFrameTime())
	{
		anim->SetCurrentFrame(anim->GetCurrentFrame() + 1);
		anim->SetFrameTime(0.0f);
	}
}

// Use this function once per frame to update all of the Animations in the manager
void CAnimationManager::UpdateAllAnimations(float elapsedTime)
{
	for(unsigned int i = 0; i < m_vAnimations.size(); ++i)
		UpdateAnimation(elapsedTime, i);
}
